import { defineComponent, computed, PropType, VNode } from "vue";
import { reduce } from "lodash";
import { TextComponentProps } from "../defaultProps";
import { mapPropsToForms } from "../propsMap";
import { Input, InputNumber, Slider, Radio, Select } from "ant-design-vue";

const mapToComponent = {
  "a-textarea": Input.TextArea,
  "a-input-number": InputNumber,
  "a-slider": Slider,
  "a-radio-group": Radio.Group,
  "a-radio-button": Radio.Button,
  "a-select": Select,
  "a-select-option": Select.Option,
} as any;

export interface FormProps {
  component: string;
  value: string;
  name?: string;
  extraProps?: { [key: string]: any };
  options?: { name: string | VNode; value: any }[];
  subComponent?: string;
  initalTransform?: (v: any) => any;
  valueProp: string;
  eventName: string;
  events: { [key: string]: (e: any) => void };
  afterTransform?: (v: any) => any;
}
function capitalizeFirstLetter(string: string) {
  return string.charAt(0).toUpperCase() + string.slice(1)
}

export default defineComponent({
  name: "props-table",
  props: {
    attrProps: {
      type: Object as PropType<TextComponentProps>,
    },
  },
  emits: ["change"],
  setup(props, context) {
    /**
     * reduce方法将
     * {text:'',fontSize:''}根据类型定义转换成下面形式
     * finalProps={
     * text:{
     *  component:'',
     *  name:'',
     * },
     *  fontSize:{
     *  component:'',
     *  name:'',
     * }
     * }
     */
    const finalProps = computed(() => {
      return reduce(
        props.attrProps,
        (result, value, key) => {
          const newKey = key as keyof TextComponentProps; //keyof 可以将interface里的字面量全部提取出来 使得变量拥有更多可能的类型
          const item = mapPropsToForms[newKey];
          if (item) {
            const {
              valueProp = "value",
              eventName = "change",
              initalTransform,
              afterTransform,
            } = item;
            const newItem: FormProps = {
              ...item,
              value: initalTransform ? initalTransform(value) : value,
              valueProp,
              eventName,
              events: {
                ['on' + capitalizeFirstLetter(eventName)]: (e: any) => { context.emit('change', { key, value: afterTransform? afterTransform(e) : e })}
              }
            };
            result[newKey] = newItem;
          }
          return result;
        },
        {} as { [key: string]: FormProps } //Required必选 required<PropsToForm> { [key: string]: FormProps}代表key值遵循string,且key的值范围不能超过FormProps
      );
    });
    return () => 
    <div class="props-table">
      {
        Object.keys(finalProps.value).map(key => {
          const value = finalProps.value[key]
          const ComponentName = mapToComponent[value.component]
          const SubComponent = value.subComponent ? mapToComponent[value.subComponent] : null
          const props = {
            [value.valueProp]: value.value,
            ...value.extraProps,
            ...value.events
          }
          return (
            <div key={key} class="prop-item">
              { value.name && <span class="label">{value.name}</span> }
              <div class="prop-component">
                <ComponentName {...props}>
                  { value.options && 
                    value.options.map(option => {
                      return (
                      <SubComponent value={option.value}>{option.name}</SubComponent>
                      )
                    })
                  }
                </ComponentName>
              </div>
            </div>
          )
        })
      }
    </div>
    
  },
});
